#include <iostream>

using std::cout;
using std::endl;

//函数对象：
//1、重载了()的类创建的对象
//2、函数指针
//3、函数名，比如test()

int func()
{
    cout << "int func()" << endl;
    return 10;
}

int func2()
{
    cout << "int func2()" << endl;
    return 20;
}

int func3(int x, int y)
{
    cout << "int func3(int, int)" << endl;
    return x + y;
}

void test()
{
    // 1、反人类的C
    typedef int (*pFunc)();//ok,C的写法 
    /* typedef int (*)() pFunc;//error,错误的语法 */
    // void*(*func)(void*)，func f，f指向一个参数为void *，返回类型为 void* 的函数
    // void(*func)() 等价于 void(*func)()，即f指向的函数是无参的
    // void(*func)(void*) 不等价于 void(*func)()
    // 如果一个函数返回的是一个指针，又不确定指针类型，这时可以用void*
    // 比如malloc返回类型就是void*，int* ptr = (int*)malloc(sizeof(int));
    
    // 2、正统的C++
    //using pFunc = int (*)();//C++的写法

    func();
    cout << "hello world" << endl;

    //延迟了函数func的调用:C++中的多态就是延迟调用的思想
    //将函数的注册与执行分开了
    //func也被称为回调函数，当需要时再回来执行调用，
    //像钩子一样，先吊着，等需要时再用
    //注册回调函数与执行回调函数
    
    // 3、直接创建对象
    cout<<endl;
    int(*a)();  //创建一个指向无参无返回类型函数的指针a
    //int(*a)()=func;
    //int(*)() a; 没有这个写法
    a=func;
    a();
    cout<<&a<<endl;
    cout<<a<<endl;
    cout<<a()<<endl;
//==================================================================
    cout << endl;
    pFunc f = func;//将func注册给了f
    //....
    //.....
    cout << "hello kiki" << endl;
    cout <<"f() = " << f() << endl;//执行了f，也就是执行func

    cout << endl;
    f = &func2;
    cout <<"f() = " << f() << endl;

    // f = &func3; 函数形态\类型 不一样，int无参的函数指针 不能绑定到 int(有参有参)
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}


